home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 2.toast / pc / sample code / processes / mp threaded sort / mpblitter.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  7.6 KB  |  303 lines

  1. /*
  2.     File:        MPBlitter.c
  3.  
  4.     Contains:    This is a simple blitter to allow my MPtask to blit to the screen.
  5.                 I was going to add masked blitting that honored the visRgn and clip
  6.                 regions so that it didn't color outside the lines. I haven't done that 
  7.                 yet. 
  8.  
  9.                 Since the original SortPicts program that I used only works with 
  10.                   8 bit images I didn't spend any time adding any other cases to the 
  11.                 blitter. If I ever get time I'll finish the blitter to be more useful
  12.                 as a generic CopyBits routine for MP.
  13.  
  14.     Written by: Matthew Xavier Mora    
  15.  
  16.     Copyright:    Copyright © 1996-1999 by Apple Computer, Inc., All Rights Reserved.
  17.  
  18.                 You may incorporate this Apple sample source code into your program(s) without
  19.                 restriction. This Apple sample source code has been provided "AS IS" and the
  20.                 responsibility for its operation is yours. You are not permitted to redistribute
  21.                 this Apple sample source code as "Apple sample source code" after having made
  22.                 changes. If you're going to re-distribute the source, we require that you make
  23.                 it clear in the source that the code was descended from Apple sample source
  24.                 code, but that you've made changes.
  25.  
  26.     Change History (most recent first):
  27.                 7/27/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  28.                 
  29.  
  30. */
  31.  
  32. #include "MPBlitter.h"
  33. #include <Multiprocessing.h>
  34.  
  35. //-----------------------------------------------------------------------------------
  36. pascal void MPCopyBits(BitMapPtr srcBits, BitMapPtr dstBits, Rect *srcRect, Rect *dstRect,short mode, RgnHandle mask)
  37. //-----------------------------------------------------------------------------------
  38. {
  39. #pragma unused (mode)
  40.     PixMapPtr            srcPM;
  41.     PixMapPtr            dstPM;
  42.     long                dstLeft;
  43.     long                dstRight;
  44.     long                srcLeft;
  45.     long                srcRowBytes;
  46.     long                dstRowBytes;
  47.     char *                srcRow;
  48.     char *                dstRow;
  49.     char *                srcPtr;
  50.     char *                dstPtr;
  51.     long                 height;
  52.     long                width;
  53.     long                 i;
  54.     long                offset;
  55.     MPCriticalRegionID    blitterBusy;
  56.     
  57.     blitterBusy = (MPCriticalRegionID)mask;
  58.     (void)MPEnterCriticalRegion(blitterBusy, kDurationForever);
  59.  
  60.     if (dstRect->top == dstRect->bottom) {
  61.         // a simple flag to say that the image is not ready
  62.         goto exit;
  63.     }     
  64.     srcPM = (PixMapPtr) srcBits;
  65.     dstPM = (PixMapPtr) dstBits;
  66.      
  67.     srcRow = (char *) srcPM->baseAddr;
  68.     dstRow = (char *) dstPM->baseAddr;
  69.  
  70.     srcRowBytes = (srcPM->rowBytes & 0x3fff);
  71.     dstRowBytes = (dstPM->rowBytes & 0x3fff);
  72.  
  73.     // get the bit offset to the src left edge
  74.     srcLeft = srcRect->left - srcPM->bounds.left;
  75.     srcLeft *= srcPM->pixelSize;
  76.     srcRow += srcLeft;
  77.  
  78.     // get the bit offset to the dst left and right edges
  79.     dstLeft = dstRect->left - dstPM->bounds.left;
  80.     dstLeft *= dstPM->pixelSize;
  81.     dstRight = dstRect->right - dstPM->bounds.left;
  82.     dstRight *= dstPM->pixelSize;
  83.     dstRow += dstLeft >> 3;
  84.         
  85.     // offset the src and dst ptrs to the first row
  86.     offset = srcRect->top - srcPM->bounds.top;
  87.     offset *= srcRowBytes  ;
  88.     srcRow += offset;
  89.  
  90.     offset = dstRect->top - dstPM->bounds.top;
  91.     offset *= dstRowBytes ;
  92.     dstRow += offset;
  93.  
  94.     height = dstRect->bottom - dstRect->top - 1;
  95.     width = dstRect->right - dstRect->left - 1;
  96.     width *= (dstPM->pixelSize >> 3);
  97.  
  98.     if (srcPM->pixelSize != dstPM->pixelSize) {
  99.         // ACK!
  100.     }
  101.     switch (dstPM->pixelSize) {
  102.         case 8:
  103.             while (height--) {
  104.                 srcPtr = srcRow;
  105.                 dstPtr = dstRow;
  106.                 
  107.                 for (i = 0 ;i < width >> 2;i++) 
  108.                 {
  109.                     *dstPtr  = *srcPtr;
  110.                     ++srcPtr;
  111.                     ++dstPtr;
  112.                     *dstPtr  = *srcPtr;
  113.                     ++srcPtr;
  114.                     ++dstPtr;
  115.                     
  116.                     *dstPtr  = *srcPtr;
  117.                     ++srcPtr;
  118.                     ++dstPtr;
  119.                     
  120.                     *dstPtr  = *srcPtr;
  121.                     ++srcPtr;
  122.                     ++dstPtr;                            
  123.                 }
  124.  
  125.                 switch ( width % 4) {
  126.                     case 3:
  127.                     *dstPtr  = *srcPtr;
  128.                     ++srcPtr;
  129.                     ++dstPtr;                    
  130.                     case 2:
  131.                     *dstPtr  = *srcPtr;
  132.                     ++srcPtr;
  133.                     ++dstPtr;                    
  134.                     case 1:
  135.                     *dstPtr  = *srcPtr;
  136.                     ++srcPtr;
  137.                     ++dstPtr;                    
  138.                     
  139.                 }
  140.                 srcRow +=  srcRowBytes;
  141.                 dstRow +=  dstRowBytes;
  142.             }
  143.             break;
  144.         case  16:
  145.             break;
  146.         case 32:
  147.             break;
  148.     }
  149.     
  150. exit:
  151.     (void)MPExitCriticalRegion(blitterBusy);
  152. }
  153.  
  154.  
  155. static pascal void CopyBlit(PixMapPtr srcPM, PixMapPtr dstPM, Rect *srcRect, Rect *dstRect)
  156. {
  157.     long            dstLeft;
  158.     long            dstRight;
  159.     long *            srcRow;
  160.     long *            dstRow;
  161.     register long *    srcPtr;
  162.     register long *    dstPtr;
  163.     long            leftMask;
  164.     long            notLeftMask;
  165.     long            rightMask;
  166.     long            notRightMask;
  167.     long            dstLong;
  168.     short            dstLongs;
  169.     short            localheight;// = height;
  170.     long            offset;
  171.     long            timesCopy;
  172.     
  173.      short    height;
  174.      long        srcRowBytes;
  175.      long        dstRowBytes;
  176.      long        srcLeft;
  177.     
  178.     localheight = height = srcRect->bottom - srcRect->top;    // No scaling allowed
  179.     
  180.     srcRowBytes = srcPM->rowBytes & 0x3fff;
  181.     dstRowBytes = dstPM->rowBytes & 0x3fff;
  182.     
  183.     // get the bit offset to the src left edge
  184.     srcLeft = (srcRect->left - srcPM->bounds.left) * srcPM->pixelSize;
  185.  
  186.     srcRow = (long *) srcPM->baseAddr;
  187.     dstRow = (long *) dstPM->baseAddr;
  188.         
  189.     // offset the src ptr to the first long
  190.     srcRow += srcLeft >> 5;
  191.     
  192.     // get the bit offset to the dst left and right edges
  193.     dstLeft = (dstRect->left - dstPM->bounds.left) * dstPM->pixelSize;
  194.     dstRight = (dstRect->right - dstPM->bounds.left) * dstPM->pixelSize;
  195.     
  196.     // get the number of middle longs to do minus the left edge long
  197.     dstLongs = ((dstRight - dstLeft) >> 5) - 1;
  198.     
  199.     // offset the dst Ptr to the first long
  200.     dstRow += dstLeft >> 5;
  201.  
  202.     // now compute left and right masks for the dst
  203.     dstLeft &= 0x1f;
  204.     leftMask = ( 1 << dstLeft ) - 1;
  205.     notLeftMask = ~leftMask;
  206.     
  207.     dstRight &= 0x1f;
  208.     notRightMask = ( 1 << dstRight ) - 1;
  209.     rightMask = ~notRightMask;
  210.     
  211.     // offset the src and dst ptrs to the first row
  212.     offset = (srcRect->top - srcPM->bounds.top) * srcRowBytes;
  213.     srcRow +=  offset >> 2;
  214.     
  215.     offset = (dstRect->top - dstPM->bounds.top) * dstRowBytes;
  216.     dstRow +=  offset >>2;
  217.     
  218.     /* check if we need to do the left and right mask */
  219.     if ( leftMask )
  220.         {
  221.         if ( notLeftMask == 0 )
  222.             {
  223.             leftMask = 0;
  224.             dstLongs++;
  225.             }
  226.         }
  227.         
  228.     if ( rightMask )
  229.         {
  230.         if ( notRightMask == 0 )
  231.             {
  232.             rightMask = 0;
  233.             dstLongs++;
  234.             }
  235.         }
  236.         
  237.     //for ( ; localheight >= 0; --localheight )
  238.     // changing the above 'for()' to the below 'while()' is what made this blit routine
  239.     // faster than CopyBits - a speed improvement equal to all other changes I had made
  240.     // previously.  (about 4 to 5 milliseconds, in case you were wondering)
  241.     // Lesson: the true bottlenecks are not always the obvious ones
  242.     while (localheight--)
  243.         {
  244.         srcPtr = srcRow;
  245.         dstPtr = dstRow;
  246.         
  247.         /* do the masked left edge */
  248.         if ( leftMask )
  249.             {
  250.             dstLong = *srcPtr++ & leftMask;
  251.             dstLong |= *dstPtr & notLeftMask;
  252.             *dstPtr++ = dstLong;
  253.             }
  254.  
  255.         /* do the middle longs with Duff's device */
  256.         timesCopy = (dstLongs + 15) >> 4;
  257.         
  258.         switch( dstLongs & 0xF )
  259.             {
  260.             case 0:    do
  261.                     {    *dstPtr++ = *srcPtr++;
  262.             case 15:    *dstPtr++ = *srcPtr++;
  263.             case 14:    *dstPtr++ = *srcPtr++;
  264.             case 13:    *dstPtr++ = *srcPtr++;
  265.             case 12:    *dstPtr++ = *srcPtr++;
  266.             case 11:    *dstPtr++ = *srcPtr++;
  267.             case 10:    *dstPtr++ = *srcPtr++;
  268.             case 9:        *dstPtr++ = *srcPtr++;
  269.             case 8:        *dstPtr++ = *srcPtr++;
  270.             case 7:        *dstPtr++ = *srcPtr++;
  271.             case 6:        *dstPtr++ = *srcPtr++;
  272.             case 5:        *dstPtr++ = *srcPtr++;
  273.             case 4:        *dstPtr++ = *srcPtr++;
  274.             case 3:        *dstPtr++ = *srcPtr++;
  275.             case 2:        *dstPtr++ = *srcPtr++;
  276.             case 1:        *dstPtr++ = *srcPtr++;
  277.                     } while( --timesCopy > 0 );
  278.             }
  279.  
  280.         /* do the masked right edge */
  281.         if ( rightMask )
  282.             {
  283.             dstLong = *srcPtr & rightMask;
  284.             dstLong |= *dstPtr & notRightMask;
  285.             *dstPtr = dstLong;
  286.             }
  287.         
  288.         /* bump to the next row */
  289.         srcRow +=  srcRowBytes >>2;
  290.         dstRow +=  dstRowBytes >>2;
  291.         }
  292.         
  293. }
  294.  
  295. static pascal void betterMPCopyBits(BitMapPtr srcBits, BitMapPtr dstBits,
  296.                 Rect *srcRect, Rect *dstRect, 
  297.                 short mode, RgnHandle mask)
  298. {
  299. #pragma unused (mode,mask)
  300.      CopyBlit((PixMapPtr) srcBits, (PixMapPtr) dstBits,srcRect, dstRect);
  301.      
  302. }
  303.